/**
 * 
 */
package cn.gov.msa.service.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import cn.gov.msa.collection.LdapService;
import cn.gov.msa.collection.SmsService;
import cn.gov.msa.collection.TransportDataService;
import cn.gov.msa.collection.WxService;
import cn.gov.msa.dao.ApplyMapper;
import cn.gov.msa.dao.FlowTaskUserMapper;
import cn.gov.msa.dao.MessageLogBakMapper;
import cn.gov.msa.dao.MessageLogMapper;
import cn.gov.msa.dao.RecordSafetyWorkInlandMapper;
import cn.gov.msa.dao.RecordSafetyWorkPortMapper;
import cn.gov.msa.dao.ReserveMapper;
import cn.gov.msa.dao.ShipMapper;
import cn.gov.msa.dao.SuperInspecRecordMapper;
import cn.gov.msa.dao.SuperviseMapper;
import cn.gov.msa.dao.SupervisioRecordMapper;
import cn.gov.msa.dao.WatersWorkMapper;
import cn.gov.msa.model.Apply;
import cn.gov.msa.model.FlowTaskUser;
import cn.gov.msa.model.MessageLog;
import cn.gov.msa.model.RecordSafetyWorkInland;
import cn.gov.msa.model.RecordSafetyWorkPort;
import cn.gov.msa.model.Reserve;
import cn.gov.msa.model.SuperInspecRecord;
import cn.gov.msa.model.SupervisioRecord;
import cn.gov.msa.model.SupervisioRule;
import cn.gov.msa.model.UserDetail;
import cn.gov.msa.model.WatersWork;
import cn.gov.msa.pagehelper.CustomPageHelper;
import cn.gov.msa.service.TaskSchedulingService;
import cn.gov.msa.util.DateUtils;
import cn.gov.msa.util.JsonDateValueProcessor;
import cn.gov.msa.util.PropertiesTools;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

/**
 * @author Administrator
 *
 */
public class TaskSchedulingServiceImpl implements TaskSchedulingService {

	private Logger logger = Logger.getLogger(TaskSchedulingServiceImpl.class);
	
	@Autowired
	SuperInspecRecordMapper superInspecRecordMapper;
	@Autowired
	MessageLogMapper messageLogMapper;
	@Autowired
	MessageLogBakMapper messageLogBakMapper;
	@Autowired
	ApplyMapper applyMapper;
	@Autowired
	ShipMapper shipMapper;
	@Autowired
	WatersWorkMapper watersWorkMapper;
	@Autowired
	RecordSafetyWorkInlandMapper recordSafetyWorkInlandMapper;
	@Autowired
	RecordSafetyWorkPortMapper recordSafetyWorkPortMapper;
	@Autowired
	ReserveMapper reserveMapper;
	@Autowired
	FlowTaskUserMapper flowTaskUserMapper;
	@Autowired
	private SuperviseMapper superviseMapper;
	@Autowired
	private SupervisioRecordMapper supervisioRecordMapper;

	@Override
	public void superInspecByTask() throws Exception {

		List<SuperInspecRecord> superInspecRecordList = superInspecRecordMapper.selectByStatus(0);
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor("yyyy-MM-dd HH:mm:ss"));
		String pushResult = "";
		for (SuperInspecRecord superInspecRecord : superInspecRecordList) {
			try {
				String applyid = superInspecRecord.getApplyid();
				Apply apply = applyMapper.selectByPrimaryKey(applyid);

				superInspecRecord.setSenddate(new Date());

				if ("1002".equals(apply.getItemno())) { // 通航水域水上水下活动作业许可申请
					WatersWork watersWork = watersWorkMapper.selectByPrimaryKey(applyid);
					
					JSONObject jsonBusiness = JSONObject.fromObject(watersWork, jsonConfig);
					JSONArray jaShip = JSONArray.fromObject(shipMapper.selectByApplyid(applyid));
					
			    	
					JSONObject jsonResult = new JSONObject();
					jsonResult.put("apply", JSONObject.fromObject(apply, jsonConfig));
					jsonResult.put("business", jsonBusiness);
					if (jaShip.size() > 0){
						jsonResult.put("ship", jaShip);
					}

					pushResult = TransportDataService.sendWatersWork(jsonResult.toString(), superInspecRecord);
					
				} else if ("1015".equals(apply.getItemno())) { // 内河通航水域安全作业备案申请
					RecordSafetyWorkInland recordSafetyWorkInland = recordSafetyWorkInlandMapper.selectByPrimaryKey(applyid);
					
					JSONObject jsonBusiness = JSONObject.fromObject(recordSafetyWorkInland, jsonConfig);
					
					JSONObject jsonResult = new JSONObject();
					jsonResult.put("business", jsonBusiness);

					JSONArray jaShip = JSONArray.fromObject(shipMapper.selectByApplyid(applyid));
					if (jaShip.size() > 0){
						jsonResult.put("ship", jaShip);
					}
					
					pushResult = TransportDataService.sendAdministrativeRecord("1015", jsonResult.toString(), superInspecRecord);
					
				} else if ("2002".equals(apply.getItemno())) { // 船舶在港区水域内安全作业备案申请
					RecordSafetyWorkPort recordSafetyWorkPort = recordSafetyWorkPortMapper.selectByPrimaryKey(applyid);
					
					JSONObject jsonBusiness = JSONObject.fromObject(recordSafetyWorkPort, jsonConfig);
					jsonBusiness.put("orgcode", apply.getOrgcode());
					
					JSONObject jsonResult = new JSONObject();
					jsonResult.put("business", jsonBusiness);
					
					JSONArray jaShip = JSONArray.fromObject(shipMapper.selectByApplyid(applyid));
					if (jaShip.size() > 0){
						jsonResult.put("ship", jaShip);
					}
					
					pushResult = TransportDataService.sendAdministrativeRecord("2002", jsonResult.toString(), superInspecRecord);
					
				} else {
					System.out.println("未知类型？" + apply.getItemno());
					continue;
				}

				if (!"".equals(pushResult)) {
					if ("1".equals(JSONObject.fromObject(pushResult).optString(""))) {
						superInspecRecord.setStatus(Short.valueOf("1"));
					}
				}
				superInspecRecord.setSyslastupd(new Date());
				superInspecRecord.setReplydate(new Date());
				superInspecRecord.setReplycontent(pushResult.toString());
				superInspecRecordMapper.updateByPrimaryKey(superInspecRecord);

			} catch (Exception e) {
				logger.error("与船舶监管平台对接异常", e);
			}

		}
	}

	@Override
	public void sendMessageByTask() {
		
		int pageSize = 10;
		int pageIndex = 1;
		List<MessageLog> messageLogList = new ArrayList<MessageLog>();
		// 分页查询，每次查询10条未发送的信息记录，防止数据量太多而导致内存溢出。
//		do {
			CustomPageHelper.startPage(pageIndex, pageSize); // 核心分页代码
			messageLogList = messageLogMapper.selectByStatus(0);
			for (MessageLog messageLog : messageLogList) {
				messageLog.setMessagedate(DateUtils.getNow());
				JSONObject notify = this.generateWxTemplate(messageLog);
				switch (messageLog.getRemindtype()) {
					case "1": // 短信
						try {
							JSONObject smsResp = SmsService.sendSingleMessage(messageLog.getPhone(), messageLog.getMessage());
							// 保存发送结果
							this.recordMessage(messageLog, smsResp);
						} catch (Exception e) {
							logger.error("短信发送异常: " + JSONObject.fromObject(messageLog), e);
						}
						break;
					case "2": // 微信
						try {
							JSONObject wxResp = WxService.notify(notify);
							// 保存发送结果
							messageLog.setMessage(notify.toString());
							this.recordMessage(messageLog, wxResp);
						} catch (Exception e) {
							logger.error("微信发送异常: " + JSONObject.fromObject(messageLog), e);
						}
						break;
					case "3": // 微信和短信
						try { // 短信
							JSONObject smsResp = SmsService.sendSingleMessage(messageLog.getPhone(), messageLog.getMessage());
							// 保存发送结果
							messageLog.setRemindtype("1");
							this.recordMessage(messageLog, smsResp);
						} catch (Exception e) {
							logger.error("短信发送异常: " + JSONObject.fromObject(messageLog), e);
						}
						
						try { // 微信
							JSONObject wxResp = WxService.notify(notify);
							// 保存发送结果
							messageLog.setRemindtype("2");
							messageLog.setMessage(notify.toString());
							this.recordMessage(messageLog, wxResp);
						} catch (Exception e) {
							logger.error("微信发送异常: " + JSONObject.fromObject(messageLog), e);
						}
						break;
	
					default:
						break;
				}
				// 删除信息发送表
				messageLogMapper.deleteByPrimaryKey(messageLog.getMessagelogid());
			}
//		} while(messageLogList.size() == pageSize);
		
	}

	@Override
	public void remindReserve() {
		String message = "%s，您好！您申请的“%s” 办事预约(%s)，受理单号：%s，请提前10分钟到现场等待。";
		// 获取当天办事预约的用户预约数据
		List<Reserve> reserveDataList = reserveMapper.selectRemindData();
		
		MessageLog messageLog = new MessageLog();
		messageLog.setRemindtype("3"); // 微信和短信
		for (Reserve reserve : reserveDataList) {
			try {
				message = String.format(message, reserve.getUSERNAME(), reserve.getITEMNAME(),
						reserve.getRECORDDATE() + " " + reserve.getRECORDPERIOD(), reserve.getBESPEAKNO(),
						reserve.getORGNAME());
				messageLog.setMessagedate(DateUtils.getNow());
				messageLog.setMessage(message);
				messageLog.setPhone(reserve.getPHONENUM());
				JSONObject smsResp = SmsService.sendSingleMessage(reserve.getPHONENUM(), message);
				if("1".equals(smsResp.optString("result"))){
					messageLog.setIssuccess(Short.valueOf("1"));
				} else {
					messageLog.setIssuccess(Short.valueOf("2"));
				}
				messageLog.setReturnmessage(smsResp.toString());
				messageLog.setReturndate(new Date());
				messageLogMapper.insertSelective(messageLog);
			} catch (Exception e) {
			}
		}
	}

	@Override
	public void remindLimitSupervise() {
		Map<String, Object> map = new HashMap<String, Object>();
		
		// 获取监察规则
		List<SupervisioRule> ruleList = superviseMapper.ruleList(map);
		SupervisioRecord supervisioRecord = new SupervisioRecord();
		// 根据规则查询需要监察的申报业务
		for (SupervisioRule supervisioRule : ruleList) {
			if("01".equals(supervisioRule.getRemindruletype())) {
				map.put("itemNo", supervisioRule.getItemno());
				map.put("limit", supervisioRule.getRemindrule());
				List<Map> remindList = superviseMapper.limitList(map);
				for (Map remind : remindList) {
					boolean flag = false;
					supervisioRecord.setRuleid(supervisioRule.getRuleid());
					supervisioRecord.setObectid((String)remind.get("applyno"));
					// 获取符合条件的最近一条监察记录 
					SupervisioRecord sup = supervisioRecordMapper.selectLastestByParam(supervisioRecord);
					
					// 提醒频率类型
					String rateType = supervisioRule.getRemindrateunit();
					// 判断提醒频率类型，转换成同意时间单位（小时）进行对比
					int hours = supervisioRule.getRemindrate();
					if ("02".equals(rateType)){ // 天
						hours = hours * 24;
					} else if ("03".equals(rateType)){ // 周（7天）
						hours = hours * 24 * 7;
					} else if ("04".equals(rateType)){ // 季度(90天)
						hours = hours * 24 * 90;
					}
					
					if(sup != null){
						// 提醒时效(小时)
						int maxHours = supervisioRule.getRemindprescription() * 24;
						// 最近一次监察与当前时间相隔时间（小时）
						int betweenHours = DateUtils.getBetweenHours(sup.getSupervisiorecorddate(), new Date()).intValue();
						// 若间隔时间大于监察频率时间并且小于提醒时效，则插入一条监察记录以及短信发送记录
						if(betweenHours >= hours && betweenHours <= maxHours){
							flag = true;
						}
					} else {
						flag = true;
					}
					
					if(flag){
						supervisioRecord.setDaylimit(((BigDecimal) remind.get("timelimit")).intValue());
						supervisioRecord.setDayused(((BigDecimal)  remind.get("userdtime")).intValue());
						supervisioRecord.setNodename((String) remind.get("nodename"));
						supervisioRecord.setRemindtype(supervisioRule.getRemindtype());
						supervisioRecord.setRemindtime(hours);
						try {
							String nowTime = DateUtils.date2String(new Date(), "yyyy-MM-dd HH:00:00");
							supervisioRecord.setSupervisiorecorddate(DateUtils.string2Date(nowTime, "yyyy-MM-dd HH:00:00"));
						} catch (ParseException e) {
							logger.error("日期类型转换异常。", e);
						}
						supervisioRecordMapper.insertSelective(supervisioRecord);
						
						// 查询受理用户
						JSONObject taskId = new JSONObject();
						taskId.put("taskid", remind.get("flowtaskid"));
						List<FlowTaskUser> taskUsers = flowTaskUserMapper.selectByParam(taskId);
						if(taskUsers != null && !taskUsers.isEmpty()){
							MessageLog messageLog = new MessageLog();
							messageLog.setRemindtype(supervisioRule.getRemindtype()); // 微信和短信
							for (FlowTaskUser flowTaskUser : taskUsers) {
								String message = "%s，您好！您有一个业务还未处理，单号：%s，请尽快处理。";
								message = String.format(message, flowTaskUser.getUsername(), (String)remind.get("applyno"), (String)remind.get("orgname"));
								messageLog.setMessage(message);
								if("1".equals(PropertiesTools.readProperties("sys.isintegration"))){
									try {
										// 调用4A接口获取处理用户的手机号码
										UserDetail userDetail = LdapService.getUserDetail(flowTaskUser.getUserid(), 0);
										messageLog.setPhone(userDetail.getMobile()); // 未知
									} catch (Exception e) {
										logger.error("调用4A接口获取受理用户异常。", e);
									}
								}
								messageLogMapper.insertSelective(messageLog);
							}
						} else {
							logger.info("未获取到受理用户。taskid=" + taskId.optString("taskid"));
						}
					}
				}
			} else {
				map.put("itemno", supervisioRule.getItemno());
				if("02".equals(supervisioRule.getRemindruletype())) { // 处理速度
					map.put("handleLimit", supervisioRule.getRemindrule());
				} else if("03".equals(supervisioRule.getRemindruletype())) { // 服务态度
					map.put("serviceLimit", supervisioRule.getRemindrule());
				}
				// 获取符合规则的申报记录
				List<Apply> applyList = applyMapper.selectLimitData(map);
				for (Apply apply : applyList) {
					boolean flag = false;
					supervisioRecord.setRuleid(supervisioRule.getRuleid());
					supervisioRecord.setObectid(apply.getApplyno());
					// 获取符合条件的最近一条监察记录 
					SupervisioRecord sup = supervisioRecordMapper.selectLastestByParam(supervisioRecord);
					
					// 提醒频率类型
					String rateType = supervisioRule.getRemindrateunit();
					// 判断提醒频率类型，转换成同意时间单位（小时）进行对比
					int hours = supervisioRule.getRemindrate();
					if ("02".equals(rateType)){ // 天
						hours = hours * 24;
					} else if ("03".equals(rateType)){ // 周（7天）
						hours = hours * 24 * 7;
					} else if ("04".equals(rateType)){ // 季度(90天)
						hours = hours * 24 * 90;
					}
					
					if(sup != null){
						// 提醒时效(小时)
						int maxHours = supervisioRule.getRemindprescription() * 24;
						// 最近一次监察与当前时间相隔时间（小时）
						int betweenHours = DateUtils.getBetweenHours(sup.getSupervisiorecorddate(), new Date()).intValue();
						// 若间隔时间大于监察频率时间并且小于提醒时效，则插入一条监察记录以及短信发送记录
						if(betweenHours >= hours && betweenHours <= maxHours){
							flag = true;
						}
					} else {
						flag = true;
					}
					
					if(flag){
						supervisioRecord.setNodename(apply.getNodename());
						supervisioRecord.setRemindtype(supervisioRule.getRemindtype());
						supervisioRecord.setRemindtime(hours);
						try {
							String nowTime = DateUtils.date2String(new Date(), "yyyy-MM-dd HH:00:00");
							supervisioRecord.setSupervisiorecorddate(DateUtils.string2Date(nowTime, "yyyy-MM-dd HH:00:00"));
						} catch (ParseException e) {
							logger.error("日期类型转换异常。", e);
						}
						supervisioRecordMapper.insertSelective(supervisioRecord);
						String message = "%s，您好！您有一个业务评价未处理，单号：%s，请尽快处理。";
						MessageLog messageLog = new MessageLog();
						messageLog.setRemindtype(supervisioRule.getRemindtype()); // 微信和短信
						message = String.format(message, apply.getAcceptstaffname(), apply.getApplyno(), apply.getOrgname());
						messageLog.setMessage(message);
						if("1".equals(PropertiesTools.readProperties("sys.isintegration"))){
							try {
								// 调用4A接口获取处理用户的手机号码
								UserDetail userDetail = LdapService.getUserDetail(apply.getAcceptstaff(), 0);
								messageLog.setPhone(userDetail.getMobile()); // 未知
							} catch (Exception e) {
								logger.error("调用4A接口获取受理用户异常。", e);
							}
						}
						messageLogMapper.insertSelective(messageLog);
					}
				}
			}
			
		}
	}

	@Override
	public void tasklistFor4A() {
		
	}
	
	/**
	 * 生成微信发送模板
	 * @return
	 */
	private JSONObject generateWxTemplate(MessageLog apply){
		String content = "您好！您申请的“" + apply.getItemname() + "”业务，申请单号：" + apply.getApplyno() + "，%s。";
		String nodename = apply.getNodename();
		switch (nodename) {
			case "办结":
			case "发证":
				content = String.format(content, "已" + nodename);
				break;
			case "材料补正":
				content = String.format(content, "因材料不完整，需重新提交材料。");
				break;
			case "不予受理":
				content = String.format(content, nodename);
				break;
			default: // 已受理
				nodename = "已受理";
				content = String.format(content, nodename);
				break;
		}
		JSONObject notify = new JSONObject();
		notify.put("userId", apply.getUserid()); // 用户Id
		notify.put("content", content); // 通知详情，字数不要超过200字
		notify.put("appName", apply.getItemname()); // 申报项目
		notify.put("operation", nodename);// 流程节点
		notify.put("remark", "感谢您的关注和理解！"); // 感谢语
		notify.put("time", new SimpleDateFormat("yyyy年MM月dd日 HH:mm").format(apply.getApplytime()));// 申请时间
		notify.put("url", "");
		return notify;
	}
	
	/**
	 * 记录发送日志
	 * @return
	 */
	private MessageLog recordMessage(MessageLog messageLog, JSONObject resp){
		messageLog.setReturnmessage(resp.toString());
		
		if("1".equals(resp.optString("result"))){
			messageLog.setIssuccess(Short.valueOf("1"));
		} else {
			messageLog.setIssuccess(Short.valueOf("2"));
		}

		messageLog.setBatchid(resp.optString("batchId")); // 短信回传
		
		// 新增记录到信息日志记录表
		messageLogBakMapper.insert(messageLog);
		return messageLog;
	}
}
